package com.iwhalecloud.bss.kite.cucc.common.util.attackUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;


public class DesEncrypt {

    public static final Logger log = LoggerFactory.getLogger(DesEncrypt.class);

    Key key;

    public DesEncrypt(String str) {
        String key = Des.MD5Encode(str);
        // log.info("{}",key);
        setKey(key); // 生成密匙
    }

    public DesEncrypt() {
        setKey(Des.MD5Encode("jzjkddzx"));
    }

    /**
     * 根据参数生成KEY
     */
    public void setKey(String strKey) {
        try {
            // log.info("{}",strKey.length());
            // 对比DES
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
            this.key = keyFactory.generateSecret(new DESedeKeySpec(strKey.getBytes("UTF8")));
        }
        catch (Exception e) {
            throw new RuntimeException("Error initializing  DesEncrypt class. Cause: " + e);
        }
    }

    /**
     * 加密String明文输入,String密文输出
     */
    public String encrypt(String strMing) {
        byte[] byteMi = null;
        byte[] byteMing = null;
        String strMi = "";
        Encoder encoder = Base64.getEncoder();
        try {
            byteMing = strMing.getBytes("UTF8");
            byteMi = this.getEncCode(byteMing);
            strMi = encoder.encodeToString(byteMi);
        }
        catch (Exception e) {
            throw new RuntimeException("Error initializing DesEncrypt class. Cause: " + e);
        }
        finally {
            encoder = null;
            byteMing = null;
            byteMi = null;
        }
        return strMi;
    }

    /**
     * 解密 以String密文输入,String明文输出
     *
     * @param strMi
     * @return
     */
    public String decrypt(String strMi) {
        Decoder decoder = Base64.getDecoder();
        byte[] byteMing = null;
        byte[] byteMi = null;
        String strMing = "";
        try {
            byteMi = decoder.decode(strMi);
            byteMing = this.getDesCode(byteMi);
            strMing = new String(byteMing, "UTF8");
        }
        catch (Exception e) {
            log.warn("解密 以String密文输入失败：{}", e.getLocalizedMessage(), e);
            throw new RuntimeException("Error initializing DesEncrypt class. Cause: " + e);
        }
        finally {
            decoder = null;
            byteMing = null;
            byteMi = null;
        }
        return strMing;
    }

    /**
     * 加密以byte[]明文输入,byte[]密文输出
     *
     * @param byteS
     * @return
     */
    private byte[] getEncCode(byte[] byteS) {
        byte[] byteFina = null;
        Cipher cipher;
        try { // 对比DES
            cipher = Cipher.getInstance("DESede");
            cipher.init(Cipher.ENCRYPT_MODE, key, SecureRandom.getInstance("SHA1PRNG"));
            byteFina = cipher.doFinal(byteS);
        }
        catch (Exception e) {
            throw new RuntimeException("Error initializing DesEncrypt class. Cause: " + e);
        }
        finally {
            cipher = null;
        }
        return byteFina;
    }

    /**
     * 解密以byte[]密文输入,以byte[]明文输出
     *
     * @param byteD
     * @return
     */
    private byte[] getDesCode(byte[] byteD) {
        Cipher cipher;
        byte[] byteFina = null;
        try { // 对比DES
            cipher = Cipher.getInstance("DESede");
            cipher.init(Cipher.DECRYPT_MODE, key, SecureRandom.getInstance("SHA1PRNG"));
            byteFina = cipher.doFinal(byteD);
        }
        catch (Exception e) {
            throw new RuntimeException("Error initializing DesEncrypt class. Cause: " + e);
        }
        finally {
            cipher = null;
        }
        return byteFina;
    }

    public static void main(String[] args) {
        DesEncrypt des = new DesEncrypt("4qpl0f05mpnx");

        String str1 = "Tl06DhD2";
        // DES加密
        String str2 = des.encrypt(str1);
        log.info("{}", str2);
        DesEncrypt des1 = new DesEncrypt("4qpl0f05mpnx");
        String deStr = des1.decrypt(str2);
        log.info("{}", "密文:" + str2);
        // DES解密
        log.info("{}", "明文:" + deStr);

    }

}
